package com.syp.auth.service.base.impl;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.LinkedList;
import java.util.List;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.transaction.Transactional;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import com.syp.auth.dao.po.AppEntity;
import com.syp.auth.dao.repository.AppRepository;
import com.syp.auth.domain.vo.AppVo;
import com.syp.auth.service.base.AppServiceI;

@Service("appService")
public class AppServiceImpl implements AppServiceI {

	@Autowired
	private AppRepository appRepository;

	@Override
	public void add(AppVo app) {
		AppEntity ae = new AppEntity();
		BeanUtils.copyProperties(app, ae);
		app.setCreateTime(Calendar.getInstance().getTime());
		app.setLastUpdate(Calendar.getInstance().getTime());

		this.appRepository.save(ae);
	}

	@Override
	public void delete(Long id) {
		this.appRepository.delete(id);
	}

	@Transactional(rollbackOn = { RuntimeException.class })
	@Override
	public void deleteBatch(List<Long> ids) {
		this.appRepository.deleteBatch(ids);
	}

	@Override
	public void edit(AppVo app) {
		AppEntity appEntity = this.appRepository.findOne(app.getId());
		appEntity.setAppCode(app.getAppCode());
		appEntity.setAppName(app.getAppName());
		appEntity.setDescription(app.getDescription());
		appEntity.setLastUpdate(Calendar.getInstance().getTime());
		this.appRepository.save(appEntity);
	}

	@Override
	public AppVo get(Long id) {
		AppVo appVo = new AppVo();
		AppEntity appEntity = this.appRepository.findOne(id);
		BeanUtils.copyProperties(appEntity, appVo);
		return appVo;
	}

	@Override
	public List<AppVo> list(final AppVo app) {
		Specification<AppEntity> spec = new Specification<AppEntity>() {
			@Override
			public Predicate toPredicate(Root<AppEntity> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				List<Predicate> pList = new ArrayList<>();
				if (!StringUtils.isEmpty(app.getAppCode())) {
					pList.add(cb.like(root.get("appCode").as(String.class), "%" + app.getAppCode().trim() + "%"));
				}
				if (!StringUtils.isEmpty(app.getAppName())) {
					pList.add(cb.like(root.get("appName").as(String.class), "%" + app.getAppName().trim() + "%"));
				}
				return cb.and(pList.toArray(new Predicate[pList.size()]));
			}
		};

		String order = app.getOrder() == null ? "desc" : app.getOrder();
		String sortColumn = app.getSort() == null ? "id" : app.getSort();
		Sort sort = new Sort(Sort.Direction.fromString(order), sortColumn);
		List<AppEntity> allList = this.appRepository.findAll(spec, sort);

		List<AppVo> list = new LinkedList<>();
		if (allList != null && !allList.isEmpty()) {
			for (AppEntity ae : allList) {
				AppVo appVo = new AppVo();
				BeanUtils.copyProperties(ae, appVo);
				list.add(appVo);
			}
		}
		return list;
	}

	@Override
	public Page<AppVo> pagelist(final AppVo app) {
		Specification<AppEntity> spec = new Specification<AppEntity>() {
			@Override
			public Predicate toPredicate(Root<AppEntity> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				List<Predicate> pList = new ArrayList<>();
				if (!StringUtils.isEmpty(app.getAppCode())) {
					pList.add(cb.like(root.get("appCode").as(String.class), "%" + app.getAppCode().trim() + "%"));
				}
				if (!StringUtils.isEmpty(app.getAppName())) {
					pList.add(cb.like(root.get("appName").as(String.class), "%" + app.getAppName().trim() + "%"));
				}
				return cb.and(pList.toArray(new Predicate[pList.size()]));
			}
		};

		String order = app.getOrder() == null ? "desc" : app.getOrder();
		String sortColumn = app.getSort() == null ? "id" : app.getSort();
		Sort sort = new Sort(Sort.Direction.fromString(order), sortColumn);
		Pageable pageable = new PageRequest(app.getPage() - 1, app.getRows(), sort);
		Page<AppEntity> page = this.appRepository.findAll(spec, pageable);

		List<AppVo> list = new LinkedList<>();
		if (page.hasContent()) {
			for (AppEntity ae : page.getContent()) {
				AppVo appVo = new AppVo();
				BeanUtils.copyProperties(ae, appVo);
				list.add(appVo);
			}
		}
		return new PageImpl<>(list, pageable, page.getTotalElements());
	}

	@Override
	public boolean checkAppCodeUnique(String appcode) {
		boolean unique = false;

		AppEntity u = this.appRepository.getByAppCode(appcode);
		if (u == null) {
			unique = true;
		}
		return unique;
	}

}
